﻿/*************************************************************************************
 * 文 件 名:   HK_MouseLook
 * 
 * 描    述:   RoamingCam的控制相机抚养功能脚本
 * 
 * 版    本：  V1.0
 * 创 建 者：  谭潇杰、京产肠饭
 * 创建时间：  2022/1/28
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System;
using UnityEngine;
using UnityEngine.EventSystems;

[Serializable]
public class HK_MouseLook
{

    [SerializeField] float XSensitivity = 3f;
    [SerializeField] float YSensitivity = 3f;

    [Header("摄像机俯仰角："), SerializeField]
    float MinimumX = -25f;
    [SerializeField]
    float MaximumX = 40f;

    [Header("是否平滑运动："), SerializeField]
    float smoothSpeed = 10f;

    Quaternion characterTargetRot;
    Quaternion cameraTargetRot;

    public void Init(Transform character, Transform camera)
    {
        characterTargetRot = character.localRotation;
        cameraTargetRot = camera.localRotation;
    }

    //------------ PC端控制 --------------

    float yRot, xRot;

    Ray ray;
    RaycastHit hit;

    public void PCLookRotation(Transform character, Transform camera)
    {
        if (Input.GetMouseButton(0))
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Physics.Raycast(ray, out hit, 500); //如果碰撞检测到物体

            yRot = Input.GetAxis("Mouse X") * XSensitivity;
            xRot = Input.GetAxis("Mouse Y") * YSensitivity;
            characterTargetRot *= Quaternion.Euler(0f, yRot, 0f);
            cameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);

            cameraTargetRot = ClampRotationAroundXAxis(cameraTargetRot);
        }

        character.localRotation = Quaternion.Slerp(character.localRotation, characterTargetRot,
            smoothSpeed * Time.deltaTime);
        camera.localRotation = Quaternion.Slerp(camera.localRotation, cameraTargetRot,
            smoothSpeed * Time.deltaTime);
    }

    //------------ 移动端控制 --------------

    Touch touch;

    public void MobileLookRoatation(Transform character, Transform camera)
    {
        if (Input.touchCount >= 1)
        {
            touch = Input.GetTouch(0);
            ray = Camera.main.ScreenPointToRay(touch.position);
            Physics.Raycast(ray, out hit, 500);
        }

        if (EventSystem.current.IsPointerOverGameObject() && hit.collider == null)
            return;

        if (touch.phase == TouchPhase.Began)
        {
            yRot = 0;
            xRot = 0;
        }

        if (touch.phase == TouchPhase.Moved)
        {
            yRot = touch.deltaPosition.x * 0.18f;
            xRot = touch.deltaPosition.y * 0.18f;
            characterTargetRot *= Quaternion.Euler(0f, -yRot, 0f);
            cameraTargetRot *= Quaternion.Euler(xRot, 0f, 0f);
        }

        cameraTargetRot = ClampRotationAroundXAxis(cameraTargetRot);

        character.localRotation = Quaternion.Slerp(character.localRotation, characterTargetRot,
            smoothSpeed * Time.deltaTime);
        camera.localRotation = Quaternion.Slerp(camera.localRotation, cameraTargetRot,
            smoothSpeed * Time.deltaTime);
    }

    // 限制摄像机俯仰角
    float angleX;

    Quaternion ClampRotationAroundXAxis(Quaternion q)
    {
        q.x /= q.w;
        q.y /= q.w;
        q.z /= q.w;
        q.w = 1.0f;

        angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);
        angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);
        q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);

        return q;
    }
}
